vue手势缩放组件

您所在的位置:网站首页 vue 图片放大缩小 vue手势缩放组件

vue手势缩放组件

2024-01-13 20:03| 来源: 网络整理| 查看: 265

vue手势缩放组件 原理解析(不想看原理的朋友可以直接跳到开发步骤)

关于手势缩放,最重要的点在于如何监听手势;如何获取缩放比例;如何在缩放的同时,保证双指之间的中心点一直处于原来的位置。

首先,手势的监听可以使用如下方法:

document.addEventListener('touchstart touchmove touchend', function(e) { if (e.touches.length == 2) {  //双指触摸手势事件   }  }

缩放比例 = 开始触摸时两指间距离 / 触摸结束时两指间距离。得到缩放比例后使用transform: scale(x,y)进行缩放。

最难的是,如何保证缩放的同时,双指之间的中心点一直处于原来的位置:

假设双指之间的中心点的坐标为(x,y),则缩放k倍后,其在缩放后的坐标系中坐标为(kx, ky);

两点间的位移距离为: 水平位移sx = x – kx;  垂直位移sy = y - ky; 那么想要双指之间的中心点回到原来的位置就必须使用transform: translate(sx,sy); 平移回去。

其中,双指中心点x坐标 = (第一个手指的x坐标 - 第二个手指的x坐标)/ 2,y坐标 = (第一个手指的y坐标 - 第二个手指的y坐标)/ 2。

这里我们使用hammer.js插件,不需要自己去计算缩放比例和双指中心点,使用更简单方便。

hammer.js简介

支持的手势有:pan滑动,缩放pinch,按压press,旋转rotate,轻扫swipe,点击tap,详细属性见下官网截图:

使用方法示例:

//通过ref获取dom元素 let zoomEl = this.$refs.zoom; //初始化hammer var hammer = new Hammer(zoomEl); //缩放事件默认是关闭的,需要设置启用 hammer.get('pinch').set({ enable: true }); //监听缩放事件 hammer.on("pinchmove pinchstart pinchin pinchout",e => { //e.type 事件类型,如pinchmove //e.scale 缩放比例 //e.center 触摸点的中心 //e.deltaX X轴偏移 //e.deltaY Y轴偏移 });

事件对象完整属性:

好了,铺垫这么多,接下来该一步步实现缩放效果了,开发步骤如下: 一、安装hammer.js插件 npm install hammerjs --save 二、dom元素布局 三、style样式设置 .test{ transform-origin: 0 0; } .test img{ width: 100%; height: 100%; } 四、js监听手势实现缩放

这里我们把手势操作单独封装到一个js文件当中,如:zoom.js文件。

import Hammer from 'hammerjs'//引用hammerjs //定义缩放方法,接收一个element参数:使用export暴露该方法 export function zoomElement(el){ var x = 0;//x轴偏移 var y = 0;//y轴偏移 var lastScale = 1;//上次缩放值 var currentScale = 1;//当前缩放值 var center;//双指中心点 //初始化hammer var hammer = new Hammer(el); //缩放事件默认是关闭的,需要设置启用 hammer.get('pinch').set({ enable: true }); //监听缩放事件 hammer.on("pinchmove pinchstart pinchin pinchout",e => { //缩放开始时获取上一次缩放值与双指中心点 if(e.type == "pinchstart"){ lastScale = currentScale || 1; center = e.center; console.log("centerX:"+center.x) console.log("centerY:"+center.y) } //当前缩放值 = 上一次缩放值 * 缩放比例 currentScale = lastScale * e.scale; //如果缩放值小于1,重置为1 if (currentScale < 1){ currentScale = 1; } //偏移量 = 双指中心点 - 当前缩放值 * 双指中心点 = 双指中心点 *(1-当前缩放值) x = center.x * (1-currentScale) y = center.y * (1-currentScale) //设置transform el.style.transform="translateX("+(x)+"px)"+"translateY("+(y)+"px)"+"scale(" + (currentScale)+ ")" }); //监听滑动事件 hammer.on('panright panleft panup pandown',(e)=>{ //滑动时:偏移量 = 滑动距离 + 当前偏移量 var translateX = e.deltaX + x var translateY = e.deltaY + y //如果偏移X值大于0:表示视图已经滑到最左侧,重置为0 if (translateX > 0){ translateX = 0 } //如果偏移Y值大于0:表示视图已经滑到最顶部,重置为0 if (translateY > 0){ translateY = 0 } //如果偏移X值小于(屏幕宽度-元素宽度):表示视图已经滑到最左侧,重置为0 //屏幕宽度 = el.clientWidth //元素宽度 = el.getBoundingClientRect().width if (translateX < el.clientWidth - el.getBoundingClientRect().width){ translateX = el.clientWidth - el.getBoundingClientRect().width } //如果偏移Y值大于(屏幕高度-元素高度):表示视图已经滑到最左侧,重置为0 //屏幕高度 = el.clientHeight //元素高度 = el.getBoundingClientRect().height if (translateY < el.clientHeight - el.getBoundingClientRect().height){ translateY = el.clientHeight - el.getBoundingClientRect().height } //设置transform el.style.transform="translateX("+(translateX)+"px)"+"translateY("+(translateY)+"px)"+"scale(" + (currentScale)+ ")" }); hammer.on('panend',(e)=>{ //滑动结束:记录当前偏移量 x = e.deltaX + x; y = e.deltaY + y; console.log("panendx:"+x) console.log("panendy:"+y) }) } 五、引用zoom.js文件,传入需要缩放的组件。 import {zoomElement} from '@/assets/static/js/zoom.js'; export default { name: 'zoom', data() { return { }; }, mounted() { //获取需要缩放的dom元素 let zoomEl = this.$refs.test; console.log("zoomEl:"+zoomEl) zoomElement(zoomEl) } } 大功告成!

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3